import axios, { AxiosRequestConfig } from 'axios'
import { showToast } from 'vant'
import 'vant/es/toast/style'

import { PendingType, Http } from './request-hqx'
import { useUserStore } from '@/stores/user'
const whiteList = ['/platform/document/url/query']

//判断APP 类型
const baseURL = import.meta.env.VITE_APP_SHIP_URL

// 创建请求实例
const instance = axios.create({
  // baseURL: import.meta.env.VITE_APP_BASE_URL + '/v1',
  baseURL: baseURL,
  // 指定请求超时的毫秒数
  timeout: 10000,
  // 表示跨域请求时是否需要使用凭证
  withCredentials: false
})

console.log('🏆 ~ instance', import.meta.env)

// 设置请求头
// instance.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
// instance.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded'
// instance.defaults.headers.put['Content-Type'] = 'application/json';

// 取消重复请求
const pending: any = []

// 移除重复请求
const removePending = (config: AxiosRequestConfig) => {
  for (const key in pending) {
    const item: number = +key
    const list: PendingType = pending[key]
    // 当前请求在数组中存在时执行函数体
    if (
      list.url === config.url &&
      list.method === config.method &&
      JSON.stringify(list.params) === JSON.stringify(config.params) &&
      JSON.stringify(list.data) === JSON.stringify(config.data)
    ) {
      // 执行取消操作
      list.cancel('操作太频繁，请稍后再试')
      // 从数组中移除记录
      pending.splice(item, 1)
    }
  }
}

// 请求拦截器（发起请求之前的拦截）
instance.interceptors.request.use(
  (config): any => {
    const userStore = useUserStore()
    const url = config.url?.split('?')[0]
    if (whiteList.find((i) => i == url)) {
      config.baseURL = '/api'
    }
    // switch (config.method) {
    //     case 'get':
    //         config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
    //     case 'post':
    //         if(config.data instanceof FormData) {
    //             config.headers['Content-Type'] = 'multipart/form-data'
    //         } else {
    //             config.headers['Content-Type'] = 'application/json;charset=UTF-8'
    //         }
    //     case 'delete':
    //         config.headers['Content-Type'] = 'application/json;charset=UTF-8'
    //     case 'put':
    //         config.headers['Content-Type'] = 'application/json;charset=UTF-8'
    // }
    if (sessionStorage.getItem('type') == '岸基') {
      // 切换企业后会有域名带过来
      config.headers.tenantSubdomain = sessionStorage.getItem('subDomain') || ''
      config.headers.token = userStore.token || sessionStorage.getItem('token') || ''
      config.headers.Authorization = userStore.token || sessionStorage.getItem('token') || ''
      // 开发环境下加上这个header 不然访问不了
      if (import.meta.env.MODE == 'development') {
        config.headers.Authorization = userStore.token || sessionStorage.getItem('token') || ''
      }
    } else {
      config.headers.Authorization = userStore.token || sessionStorage.getItem('token') || ''
    }
    removePending(config)
    config.cancelToken = new axios.CancelToken((c) => {
      pending.push({ url: config.url, method: config.method, params: config.params, data: config.data, cancel: c })
    })
    /**
     * 在这里一般会携带前台的参数发送给后台，比如下面这段代码：
     * const token = getToken()
     * if (token) {
     *  config.headers.token = token
     * }
     */
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

// 响应拦截器（获取到响应时的拦截）
instance.interceptors.response.use(
  (response) => {
    console.log(response, 'response')
    removePending(response.config)
    /**
     * 根据你的项目实际情况来对 response 和 error 做处理
     * 这里对 response 和 error 不做任何处理，直接返回
     */
    if (response.status !== 200) {
      errorHandle(response.status, response.data.message)
      return Promise.reject(response)
    }
    if (response.status === 200 && response.data.code !== 200) {
      errorHandle(response.data.code, response.data.message)
      return Promise.reject(response)
    }
    return response
  },
  (error) => {
    const { response } = error

    if (response) {
      // 请求已发出，但是不在2xx的范围
      errorHandle(response.status)
    } else {
      console.log('网络连接异常,请稍后再试!')
    }

    return Promise.reject(error)
  }
)

/**
 * http握手错误
 * @param res 响应回调,根据不同响应进行不同操作
 * @param message
 */
function errorHandle(code: any, message?: string) {
  // console.log(message)
  // 状态码判断
  switch (code) {
    case 401:
      showToast({ message })
      setTimeout(() => {
        // toLogin()
      }, 1000)
      break
    case 403:
      break
    case 404:
      showToast('请求的资源不存在')
      break
    default:
      showToast({ message })

    // 错误信息判断
    // console.log(message)
  }
}

// 导出常用函数
const http: Http = {
  request(config: AxiosRequestConfig) {
    // console.log(config)
    if (config.method) {
      // @ts-ignore
      return http[config.method](config.url, config.method.toLowerCase() == 'get' ? config.params : config.data)
    }
  },
  post(url, data, type) {
    return new Promise((resolve, reject) => {
      instance
        .post(url, data, {
          headers: {
            'Content-Type': type ? type : 'application/json'
          }
        })
        .then((res) => {
          resolve(res.data)
        })
        .catch((err) => {
          reject(err.data)
        })
    })
  },
  get(url, params) {
    return new Promise((resolve, reject) => {
      instance
        .get(url, { params })
        .then((res) => {
          resolve(res.data)
        })
        .catch((err) => {
          reject(err.data)
        })
    })
  },
  put(url, data, params) {
    return new Promise((resolve, reject) => {
      instance
        .put(url, data, params)
        .then((res) => {
          resolve(res.data)
        })
        .catch((err) => {
          reject(err.data)
        })
    })
  },
  delete(url, params) {
    return new Promise((resolve, reject) => {
      instance
        .delete(url, params)
        .then((res) => {
          resolve(res.data)
        })
        .catch((err) => {
          reject(err.data)
        })
    })
  }
}

export default http
